package com.fingard.dsp.bank.directbank.cscb01;

import com.fingard.constant.Format;
import com.fingard.dsp.bank.dbobj.receipt.ReceiptData;
import com.fingard.dsp.bank.dbobj.receipt.ReceiptDataHelper;
import com.fingard.dsp.bank.directConfig.ReceiptProConfig;
import com.fingard.dsp.bank.directbank.bankInterface.IReceiptPro;
import com.fingard.dsp.bank.reqrespobj.downloadreceipt.ReqQryReceipt;
import com.fingard.dsp.bank.reqrespobj.downloadreceipt.RetAtsReceipt;
import com.fingard.io.FileHelper;
import com.fingard.text.MFSHelper;
import com.fingard.text.StringHelper;
import com.fingard.util.SmbFileUtil;
import com.fingard.xml.XElement;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

import java.io.File;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import static com.fingard.text.StringHelper.trimEndFileSp;

/**
 * 长沙银行-电子回单查询
 * @author alan
 * @date 2020-06-28
 */
public class CSCB01ReceiptPro extends CSCB01Base implements IReceiptPro {

    @Override
    public RetAtsReceipt qryReceiptOneDay(ReceiptProConfig pConfig, ReqQryReceipt pReqReceipt, Date pOneDay) throws Exception {
        //1、查询请求日期的明细数据，获取电子回单信息
        //待下载回单数据
        List<ReceiptData> receiptDataList=new ArrayList<ReceiptData>();
        //获取待下载回单数据
        CSCB01Header bankHeader = new CSCB01Header();
        bankHeader.trCode = "200110";
        bankHeader.reqNo = pReqReceipt.reqHeader.reqSeqID;
        bankHeader.fileFlag = "0";//文件标识 0-报文 1-文件
        XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
        writeCommonHeader(xmlWriter, bankHeader);
        XElement tmpXElement = new XElement("body", "");
        tmpXElement.addChild(new XElement("acno", pReqReceipt.actNum));
        tmpXElement.addChild(new XElement("cur_code", convertCurToBank(pReqReceipt.actCur)));
        tmpXElement.addChild(new XElement("start_date", Format.Date8Format.format(pReqReceipt.getDateFrom())));//查询起始日期
        tmpXElement.addChild(new XElement("end_date", Format.Date8Format.format(pReqReceipt.getDateTo())));//查询结束日期
        xmlWriter.writeXElement(tmpXElement);
        xmlWriter.writeEndDocument();
        String[] tmpStrRet = sendToBank(xmlWriter.toXmlString(), pReqReceipt.reqHeader.transType, pReqReceipt.reqHeader.transType);
        if (tmpStrRet[0].length() == 0) {
            StringBuilder tmpSbMsg = new StringBuilder();
            XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
            if (tmpBkReader != null) {
                String tmpRetCode = tmpBkReader.getFirstText("/ap/head/ret_code");
                String tmpRetInfo = tmpBkReader.getFirstText("/ap/head/ret_info");
                String succ_flag = tmpBkReader.getFirstText("/ap/head/succ_flag");
                if ("0000".equals(tmpRetCode) && "0".equals(succ_flag)) {
                    int tmpRecordNum = Integer.parseInt(tmpBkReader.getFirstTextNotNull("/ap/body/record_num"));
                    int tmpFieldNum = Integer.parseInt(tmpBkReader.getFirstTextNotNull("/ap/body/field_num"));
                    if (tmpRecordNum > 0) {
                        String tmpDataMFS = "";
                        String tmpFileFlag = tmpBkReader.getFirstText("/ap/head/file_flag");
                        if (tmpFileFlag != null && tmpFileFlag.equals("1")) {
                            String tmpBatchFileName = tmpBkReader.getFirstText("/ap/body/file_name");
                            if(StringHelper.hasAnyChar(bankFront.bkTransFolder)){
                                String downloadFilePath = trimEndFileSp(bankFront.bkTransFolder) + File.separator;//文件存放路径
                                //dsp与前置机不在同一服务器，需要设置共享目录
                                if(bankFront.bkTransFolder.contains("smb:")){
                                    StringBuilder p_sb = new StringBuilder();
                                    tmpDataMFS=SmbFileUtil.smbReadFileText(downloadFilePath,tmpBatchFileName,p_sb,getCharset());
                                }else {
                                    tmpDataMFS = FileHelper.readFileText(downloadFilePath+tmpBatchFileName, getCharset());
                                }
                            }else {
                                WriteBankLogLn("BankFront.xml的"+pReqReceipt.reqHeader.bankCode+"未配置bkTransFolder节点");
                                return null;
                            }
                        } else {
                            tmpDataMFS = tmpBkReader.getFirstText("/ap/body/serial_record");
                        }
                        if (StringHelper.hasAnyChar(tmpDataMFS)) {
                            WriteBankLogLn("获取明细内容为：\n"+tmpDataMFS);
                            StringBuilder tmpSbLog = new StringBuilder();
                            ArrayList<String[]> tmpArrayList = MFSHelper.getTextArray(tmpDataMFS, "|", tmpFieldNum, tmpRecordNum + 1, tmpSbLog);
                            if (tmpSbLog.length() == 0) {
                                         /*0平台流水号|1账号|2货币码|3交易日期|4交易时间交易日期|5主机流水号|6交易行号|7户名|8对方账号|9对方货币码|10对方账号户名|
//                                         11对方账号开户行|12对方行号|13交易类别|14钞汇标志|15他行标志|16同城异地标志|17手续费|18交易来源|19发生额标志|
//                                         20被冲销流水号|21原交易日期|22现转标志|23借贷标志|24交易金额|25余额|26上笔余额|27冻结金额|28凭证种类|29凭证批次号|
//                                         30凭证号码|31交易码|32柜员号|33传票号|34摘要|35附言|36交易时间戳|37备注字段一|38备注字段二|39交易机构名称|40借方金额|
//                                         41贷方金额|*/
                                for (int i = 1; i < tmpArrayList.size(); i++) {
                                    String[] tmpEachArr = tmpArrayList.get(i);
                                    if(tmpEachArr.length>35){
                                        int qryDate=Integer.parseInt(Format.Date8Format.format(pOneDay));
                                        int rspDate=Integer.parseInt(tmpEachArr[3]);
                                        if(qryDate==rspDate){
                                            ReceiptData eachData = new ReceiptData();
                                            /**回单唯一标识（在银行端的唯一标识（该账号的唯一），如招行的打印实例号）*/
                                            String hostId=tmpEachArr[5];
                                            eachData.istNbr=hostId;
                                            /**回单关联号（回单编号）*/
                                            eachData.receiptNo=hostId;
                                            /**业务参考号*/
                                            eachData.busRef=hostId;
                                            /**银行流水号*/
                                            eachData.bnkSeqNo=hostId;
                                            /**本方账号*/
                                            eachData.ownAct=pReqReceipt.actNum;
                                            /**银行代码，如工行102*/
                                            eachData.bank="7043";
                                            /**线路代码（来源渠道），如工行直联ICBC02*/
                                            eachData.srcSys=this.bankFront.bankCode;
                                            /**日期*/
                                            eachData.busDate=qryDate;
                                            /**对方账号*/
                                            eachData.oppActNum=tmpEachArr[8].trim();
                                            /**对方户名*/
                                            eachData.oppActName=tmpEachArr[10].trim();
                                            String cdFlag=tmpEachArr[23].trim();
                                            String transAmt=tmpEachArr[24].trim();
                                            String moneyWay="";
                                            String amount="";
                                            if(transAmt.startsWith("-")){
                                                if ("C".equals(cdFlag)) {
                                                    moneyWay = "1";
                                                } else if ("D".equals(cdFlag)) {
                                                    moneyWay = "2";
                                                }
                                                amount =transAmt.substring(1);
                                            }else {
                                                if ("C".equals(cdFlag)) {
                                                    moneyWay = "2";
                                                } else if ("D".equals(cdFlag)) {
                                                    moneyWay = "1";
                                                }
                                                amount =transAmt;
                                            }
                                            /**交易方向*/
                                            eachData.moneyWay=moneyWay;
                                            /**金额*/
                                            eachData.amount=new BigDecimal(amount);
                                            /**币种*/
                                            eachData.cur=convertCurToATS(tmpEachArr[2].trim());
                                            /**用途*/
                                            eachData.purpose=tmpEachArr[35].trim();
                                            receiptDataList.add(eachData);
                                        }
                                    }
                                }
                            } else {
                                WriteBankLogLn(tmpSbLog.toString());
                            }
                        } else {
                            WriteBankLogLn("未获取到明细数据");
                        }
                    }else {
                        WriteBankLogLn("查询日期内的数据为空");
                    }
                } else {
                    WriteBankLogLn(tmpRetInfo);
                }
            } else {
                WriteBankLogLn(tmpSbMsg.toString());
            }
        } else {
            WriteBankLogLn(tmpStrRet[1]);
        }
        int dowTotalNum=0;
        //2、根据响应的交易日期和主机流水号，请求银行下载对应的电子回单
        if(receiptDataList!=null && receiptDataList.size()>0){
            for(ReceiptData receiptData:receiptDataList){
                CSCB01Header bankHeader2 = new CSCB01Header();
                bankHeader2.trCode = "200218";
                bankHeader2.reqNo = pReqReceipt.reqHeader.reqSeqID;
                bankHeader2.fileFlag = "0";//文件标识 0-报文 1-文件
                XmlTextWriter xmlWriter2 = new XmlTextWriter();//发银行报文的XML对象
                writeCommonHeader(xmlWriter2, bankHeader2);
                XElement tmpXElement2 = new XElement("body", "");
                tmpXElement2.addChild(new XElement("acno", pReqReceipt.actNum));
                tmpXElement2.addChild(new XElement("cur_code", convertCurToBank(pReqReceipt.actCur)));
                tmpXElement2.addChild(new XElement("tr_acdt", receiptData.busDate+""));//查询起始日期
                tmpXElement2.addChild(new XElement("host_serial_no", receiptData.receiptNo));//查询结束日期
                xmlWriter2.writeXElement(tmpXElement2);
                xmlWriter2.writeEndDocument();
                String[] tmpStrRet2 = sendToBank(xmlWriter2.toXmlString());
                if (tmpStrRet2[0].length() == 0) {
                    StringBuilder tmpSbMsg = new StringBuilder();
                    XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet2[1], tmpSbMsg);
                    if (tmpBkReader != null) {
                        String tmpRetCode = tmpBkReader.getFirstText("/ap/head/ret_code");
                        String tmpRetInfo = tmpBkReader.getFirstText("/ap/head/ret_info");
                        String succ_flag = tmpBkReader.getFirstText("/ap/head/succ_flag");
                        if ("0000".equals(tmpRetCode) && "0".equals(succ_flag)) {
                            String tmpReceiptFileName = tmpBkReader.getFirstText("/ap/body/ReportFileName");
                            if(StringHelper.hasAnyChar(tmpReceiptFileName)){
                                if(StringHelper.hasAnyChar(bankFront.bkTransFolder) && StringHelper.hasAnyChar(pConfig.localSaveMainDir)){
                                    //文件存放路径
                                    String downloadFilePath = trimEndFileSp(bankFront.bkTransFolder) + File.separator;
                                    //本地统一文件存放路径
                                    String localSaveMainDir = trimEndFileSp(pConfig.localSaveMainDir) + File.separator;
                                    //dsp与前置机不在同一服务器，需要设置共享目录
                                    if(bankFront.bkTransFolder.contains("smb:")){
                                        StringBuilder p_sb = new StringBuilder();
                                        SmbFileUtil.smbDownloadInChar(localSaveMainDir,downloadFilePath,tmpReceiptFileName,p_sb);
                                    }else {
                                        FileHelper.renameTo(downloadFilePath+tmpReceiptFileName,localSaveMainDir+tmpReceiptFileName);
                                    }
                                    if(FileHelper.existFile(localSaveMainDir+tmpReceiptFileName)){
                                        /**回单文件--本地文件相对路径*/
                                        receiptData.localFile=pConfig.getPathRelativeToMain(localSaveMainDir+tmpReceiptFileName);
                                        /**源文件路径*/
                                        receiptData.srcFile=localSaveMainDir+tmpReceiptFileName;
                                        /**回单文件类型*/
                                        receiptData.fileType=tmpReceiptFileName.contains(".pdf")
                                                || tmpReceiptFileName.contains(".PDF")?"1":"2";
                                        /**下载状态：指从银行下载该回单文件的状态，1未下载；2已下载；3下载失败；4下载中*/
                                        receiptData.downState="2";
                                        /**下载时间*/
                                        receiptData.downTime=new Date();
                                        /**下载信息，如果失败则为失败原因*/
                                        receiptData.downInfo="下载成功";
                                        /**上传状态：指文件从银行端下载完成后，上传至ftp或ats或oss或客制化文件服务的状态，1未上传；2已上传；3上传失败；4上传中*/
                                        receiptData.upState="1";
                                        /**推送状态：指文件上传完成后，回单数据推送至ats或客制化平台的状态，1未推送；2已推送；3推送失败；4推送中*/
                                        receiptData.pushState="1";
                                        /**创建时间*/
                                        receiptData.createdOn=new Date();
                                        /**最后修改时间*/
                                        receiptData.lastModifiedOn=new Date();
                                        /**版本号*/
                                        receiptData.rowVersion=1;
                                        ReceiptDataHelper  receiptHelper = new ReceiptDataHelper(reqHeader.tenant, receiptData.getBusDate());
                                        //回单数据记录入库
                                        int inRe = receiptHelper.insertIfNotExist(receiptData);
                                        if(inRe>0){
                                            dowTotalNum++;
                                        }else{
                                            WriteBankLogLn(receiptData.receiptNo+"写入数据库，影响行数："+inRe);
                                        }
                                    }else {
                                        WriteBankLogLn("电子回单文件获取失败，请重新查询获取");
                                    }
                                }else {
                                    WriteBankLogLn("BankFront.xml的"+pReqReceipt.reqHeader.bankCode+"未配置" +
                                            "bkTransFolder节点，或者ReceiptPro.xml中未配置localSaveDir节点");
                                }
                            }else {
                                WriteBankLogLn("返回文件名为空");
                            }
                        } else {
                            WriteBankLogLn(tmpRetInfo);
                        }
                    } else {
                        WriteBankLogLn(tmpSbMsg.toString());
                    }
                } else {
                    WriteBankLogLn(tmpStrRet2[1]);
                }
            }
        }else {
            WriteBankLogLn("未获取到需要下载的电子回单文件");
        }
        WriteBankLogLn("需要下载电子回单数："+(receiptDataList!=null?receiptDataList.size():"0"));
        WriteBankLogLn("下载成功电子回单数："+dowTotalNum);
        return null;
    }
}
